#include "device_manager.h"
#include "logger.h"
#include <stdlib.h>
#include <string.h>

// 内部函数声明
static device_node_t *parse_device_tree_json(json_t *json);
static device_group_t *parse_tags_json(json_t *json, const char *node, const char *group);
static read_response_t *parse_read_response(json_t *json, const char *node, const char *group);
static control_response_t *parse_control_response(json_t *json);

// 设备轮询回调
static void device_polling_callback(void *arg) {
    device_manager_t *manager = (device_manager_t *)arg;
    if (!manager || !manager->initialized) {
        return;
    }

    // 遍历所有已知的设备组，读取实时数据
    pthread_rwlock_rdlock(&manager->rwlock);
    device_group_t *group = manager->groups;
    while (group) {
        read_response_t *response = device_manager_read_group(manager, group->node_name, group->group_name);
        if (response && response->tag_values) {
            // 将数据更新到数据池
            const char *tag_name;
            json_t *tag_value;
            json_object_foreach(response->tag_values, tag_name, tag_value) {
                char *data_key = device_data_to_data_pool_key(group->node_name, group->group_name, tag_name);
                if (data_key) {
                    data_pool_put(manager->data_pool, data_key, tag_value);
                    free(data_key);
                }
            }
            
            // 发送数据更新事件
            event_t *event = event_create(EVENT_DATA_UPDATE, NULL, 0, NULL);
            if (event) {
                event_loop_send_event(manager->event_loop, event);
                event_destroy(event);
            }
        }
        
        if (response) {
            // 释放响应内存
            free(response->node);
            free(response->group);
            json_decref(response->tag_values);
            free(response);
        }
        
        group = group->next;
    }
    pthread_rwlock_unlock(&manager->rwlock);
}

int device_manager_init(device_manager_t *manager, const char *base_url, 
                       event_loop_t *event_loop, timer_manager_t *timer, 
                       data_pool_t *data_pool) {
    if (!manager || !base_url || !event_loop || !timer || !data_pool) {
        return ERROR_INVALID_PARAM;
    }

    memset(manager, 0, sizeof(device_manager_t));
    
    if (pthread_rwlock_init(&manager->rwlock, NULL) != 0) {
        return ERROR_THREAD_CREATE;
    }

    manager->base_url = strdup(base_url);
    manager->event_loop = event_loop;
    manager->timer = timer;
    manager->data_pool = data_pool;
    manager->device_tree = NULL;
    manager->groups = NULL;
    manager->initialized = true;

    LOG_INFO("Device manager initialized with base URL: %s", base_url);
    return SUCCESS;
}

int device_manager_set_auth(device_manager_t *manager, const char *auth_token) {
    if (!manager || !auth_token) {
        return ERROR_INVALID_PARAM;
    }

    if (manager->auth_token) {
        free(manager->auth_token);
    }
    manager->auth_token = strdup(auth_token);
    
    return SUCCESS;
}

int device_manager_discover_devices(device_manager_t *manager) {
    if (!manager || !manager->initialized) {
        return ERROR_INVALID_PARAM;
    }

    // 构建请求URL
    char url[1024];
    snprintf(url, sizeof(url), "%s/api/v2/group", manager->base_url);

    // 使用libcurl发送GET请求
    CURL *curl = curl_easy_init();
    if (!curl) {
        return ERROR_API_CALL;
    }

    struct curl_slist *headers = NULL;
    if (manager->auth_token) {
        char auth_header[256];
        snprintf(auth_header, sizeof(auth_header), "Authorization: Bearer %s", manager->auth_token);
        headers = curl_slist_append(headers, auth_header);
    }
    headers = curl_slist_append(headers, "Content-Type: application/json");

    char *response_data = NULL;
    size_t response_size = 0;

    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_data);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);

    CURLcode res = curl_easy_perform(curl);
    long http_code = 0;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);

    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);

    if (res != CURLE_OK || http_code != 200) {
        LOG_ERROR("Failed to discover devices: HTTP %ld, CURL: %s", http_code, curl_easy_strerror(res));
        if (response_data) {
            free(response_data);
        }
        return ERROR_API_CALL;
    }

    // 解析响应
    json_error_t error;
    json_t *root = json_loads(response_data, 0, &error);
    free(response_data);

    if (!root) {
        LOG_ERROR("Failed to parse device tree JSON: %s", error.text);
        return ERROR_JSON_PARSE;
    }

    // 解析设备树
    pthread_rwlock_wrlock(&manager->rwlock);
    if (manager->device_tree) {
        // 清理旧的设备树
        // 简化实现，实际应该递归释放
    }
    manager->device_tree = parse_device_tree_json(root);
    pthread_rwlock_unlock(&manager->rwlock);

    json_decref(root);

    if (manager->device_tree) {
        LOG_INFO("Device discovery completed successfully");
        return SUCCESS;
    } else {
        LOG_ERROR("Failed to parse device tree");
        return ERROR_JSON_PARSE;
    }
}

device_node_t *parse_device_tree_json(json_t *json) {
    if (!json || !json_is_object(json)) {
        return NULL;
    }

    json_t *nodes = json_object_get(json, "nodes");
    if (!nodes || !json_is_array(nodes)) {
        return NULL;
    }

    device_node_t *root = NULL;
    device_node_t *current = NULL;

    size_t index;
    json_t *node_obj;
    json_array_foreach(nodes, index, node_obj) {
        device_node_t *new_node = malloc(sizeof(device_node_t));
        if (!new_node) {
            continue;
        }
        memset(new_node, 0, sizeof(device_node_t));

        // 解析节点基本信息
        json_t *name = json_object_get(node_obj, "name");
        if (name && json_is_string(name)) {
            new_node->name = strdup(json_string_value(name));
        }

        json_t *plugin = json_object_get(node_obj, "plugin");
        if (plugin && json_is_string(plugin)) {
            new_node->plugin = strdup(json_string_value(plugin));
        }

        // 解析子节点
        json_t *child = json_object_get(node_obj, "child");
        if (child && json_is_array(child)) {
            new_node->child = parse_device_tree_json(child); // 递归解析
        }

        // 添加到链表
        if (!root) {
            root = new_node;
            current = new_node;
        } else {
            current->next = new_node;
            current = new_node;
        }
    }

    return root;
}

int device_manager_sync_group_tags(device_manager_t *manager, const char *node, const char *group) {
    if (!manager || !node || !group) {
        return ERROR_INVALID_PARAM;
    }

    // 构建请求URL
    char url[1024];
    snprintf(url, sizeof(url), "%s/api/v2/tags", manager->base_url);

    CURL *curl = curl_easy_init();
    if (!curl) {
        return ERROR_API_CALL;
    }

    // 设置查询参数
    char query_params[256];
    snprintf(query_params, sizeof(query_params), "node=%s&group=%s", node, group);
    char full_url[1280];
    snprintf(full_url, sizeof(full_url), "%s?%s", url, query_params);

    struct curl_slist *headers = NULL;
    if (manager->auth_token) {
        char auth_header[256];
        snprintf(auth_header, sizeof(auth_header), "Authorization: Bearer %s", manager->auth_token);
        headers = curl_slist_append(headers, auth_header);
    }

    char *response_data = NULL;
    size_t response_size = 0;

    curl_easy_setopt(curl, CURLOPT_URL, full_url);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_data);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);

    CURLcode res = curl_easy_perform(curl);
    long http_code = 0;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);

    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);

    if (res != CURLE_OK || http_code != 200) {
        LOG_ERROR("Failed to sync tags for node=%s, group=%s: HTTP %ld", node, group, http_code);
        if (response_data) {
            free(response_data);
        }
        return ERROR_API_CALL;
    }

    // 解析响应
    json_error_t error;
    json_t *root = json_loads(response_data, 0, &error);
    free(response_data);

    if (!root) {
        LOG_ERROR("Failed to parse tags JSON: %s", error.text);
        return ERROR_JSON_PARSE;
    }

    // 解析标签数据
    device_group_t *device_group = parse_tags_json(root, node, group);
    json_decref(root);

    if (!device_group) {
        LOG_ERROR("Failed to parse tags for node=%s, group=%s", node, group);
        return ERROR_JSON_PARSE;
    }

    // 添加到管理器
    pthread_rwlock_wrlock(&manager->rwlock);
    
    // 检查是否已存在该组
    device_group_t *existing = manager->groups;
    device_group_t *prev = NULL;
    while (existing) {
        if (strcmp(existing->node_name, node) == 0 && strcmp(existing->group_name, group) == 0) {
            // 更新现有组
            device_group->next = existing->next;
            if (prev) {
                prev->next = device_group;
            } else {
                manager->groups = device_group;
            }
            // 释放旧的组（简化实现）
            break;
        }
        prev = existing;
        existing = existing->next;
    }
    
    // 如果是新组，添加到链表头部
    if (!existing) {
        device_group->next = manager->groups;
        manager->groups = device_group;
    }
    
    pthread_rwlock_unlock(&manager->rwlock);

    LOG_INFO("Synced tags for node=%s, group=%s, found %zu tags", node, group, device_group->tag_count);
    return SUCCESS;
}

device_group_t *parse_tags_json(json_t *json, const char *node, const char *group) {
    if (!json || !json_is_object(json)) {
        return NULL;
    }

    json_t *tags_array = json_object_get(json, "tags");
    if (!tags_array || !json_is_array(tags_array)) {
        return NULL;
    }

    device_group_t *group_obj = malloc(sizeof(device_group_t));
    if (!group_obj) {
        return NULL;
    }
    memset(group_obj, 0, sizeof(device_group_t));

    group_obj->node_name = strdup(node);
    group_obj->group_name = strdup(group);
    group_obj->last_sync = time(NULL);

    size_t tag_count = json_array_size(tags_array);
    group_obj->tags = malloc(tag_count * sizeof(device_tag_t *));
    if (!group_obj->tags) {
        free(group_obj->node_name);
        free(group_obj->group_name);
        free(group_obj);
        return NULL;
    }

    group_obj->tag_count = 0;

    size_t index;
    json_t *tag_obj;
    json_array_foreach(tags_array, index, tag_obj) {
        device_tag_t *tag = malloc(sizeof(device_tag_t));
        if (!tag) {
            continue;
        }
        memset(tag, 0, sizeof(device_tag_t));

        // 解析标签字段
        json_t *field;

        field = json_object_get(tag_obj, "type");
        if (field && json_is_integer(field)) {
            tag->type = json_integer_value(field);
        }

        field = json_object_get(tag_obj, "name");
        if (field && json_is_string(field)) {
            tag->name = strdup(json_string_value(field));
        }

        field = json_object_get(tag_obj, "attribute");
        if (field && json_is_integer(field)) {
            tag->attribute = json_integer_value(field);
        }

        field = json_object_get(tag_obj, "value");
        if (field) {
            tag->value = json_deep_copy(field);
        }

        field = json_object_get(tag_obj, "address");
        if (field && json_is_string(field)) {
            tag->address = strdup(json_string_value(field));
        }

        field = json_object_get(tag_obj, "description");
        if (field && json_is_string(field)) {
            tag->description = strdup(json_string_value(field));
        }

        group_obj->tags[group_obj->tag_count++] = tag;
    }

    return group_obj;
}

read_response_t *device_manager_read_group(device_manager_t *manager, const char *node, const char *group) {
    if (!manager || !node || !group) {
        return NULL;
    }

    // 构建请求URL和请求体
    char url[1024];
    snprintf(url, sizeof(url), "%s/api/v2/read", manager->base_url);

    CURL *curl = curl_easy_init();
    if (!curl) {
        return NULL;
    }

    // 构建请求体
    json_t *request_body = json_object();
    json_object_set_new(request_body, "node", json_string(node));
    json_object_set_new(request_body, "group", json_string(group));

    char *request_body_str = json_dumps(request_body, JSON_COMPACT);
    json_decref(request_body);

    struct curl_slist *headers = NULL;
    if (manager->auth_token) {
        char auth_header[256];
        snprintf(auth_header, sizeof(auth_header), "Authorization: Bearer %s", manager->auth_token);
        headers = curl_slist_append(headers, auth_header);
    }
    headers = curl_slist_append(headers, "Content-Type: application/json");

    char *response_data = NULL;
    size_t response_size = 0;

    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request_body_str);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_data);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);

    CURLcode res = curl_easy_perform(curl);
    long http_code = 0;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);

    curl_slist_free_all(headers);
    free(request_body_str);
    curl_easy_cleanup(curl);

    if (res != CURLE_OK || http_code != 200) {
        LOG_ERROR("Failed to read group data for node=%s, group=%s: HTTP %ld", node, group, http_code);
        if (response_data) {
            free(response_data);
        }
        return NULL;
    }

    // 解析响应
    json_error_t error;
    json_t *root = json_loads(response_data, 0, &error);
    free(response_data);

    if (!root) {
        LOG_ERROR("Failed to parse read response JSON: %s", error.text);
        return NULL;
    }

    read_response_t *response = parse_read_response(root, node, group);
    json_decref(root);

    return response;
}

read_response_t *parse_read_response(json_t *json, const char *node, const char *group) {
    if (!json || !json_is_object(json)) {
        return NULL;
    }

    read_response_t *response = malloc(sizeof(read_response_t));
    if (!response) {
        return NULL;
    }
    memset(response, 0, sizeof(read_response_t));

    response->node = strdup(node);
    response->group = strdup(group);
    response->timestamp = time(NULL);

    json_t *tags_array = json_object_get(json, "tags");
    if (!tags_array || !json_is_array(tags_array)) {
        free(response->node);
        free(response->group);
        free(response);
        return NULL;
    }

    response->tag_values = json_object();

    size_t index;
    json_t *tag_obj;
    json_array_foreach(tags_array, index, tag_obj) {
        json_t *name = json_object_get(tag_obj, "name");
        json_t *value = json_object_get(tag_obj, "value");

        if (name && json_is_string(name) && value) {
            const char *tag_name = json_string_value(name);
            json_object_set_new(response->tag_values, tag_name, json_deep_copy(value));
        }
    }

    return response;
}

control_response_t *device_manager_write_tag(device_manager_t *manager, control_request_t *request) {
    if (!manager || !request || !request->node || !request->group || !request->tag || !request->value) {
        return NULL;
    }

    // 构建请求URL
    char url[1024];
    snprintf(url, sizeof(url), "%s/api/v2/write", manager->base_url);

    CURL *curl = curl_easy_init();
    if (!curl) {
        return NULL;
    }

    // 构建请求体
    json_t *request_body = json_object();
    json_object_set_new(request_body, "node", json_string(request->node));
    json_object_set_new(request_body, "group", json_string(request->group));
    json_object_set_new(request_body, "tag", json_string(request->tag));
    json_object_set_new(request_body, "value", json_deep_copy(request->value));

    char *request_body_str = json_dumps(request_body, JSON_COMPACT);
    json_decref(request_body);

    struct curl_slist *headers = NULL;
    if (manager->auth_token) {
        char auth_header[256];
        snprintf(auth_header, sizeof(auth_header), "Authorization: Bearer %s", manager->auth_token);
        headers = curl_slist_append(headers, auth_header);
    }
    headers = curl_slist_append(headers, "Content-Type: application/json");

    char *response_data = NULL;
    size_t response_size = 0;

    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request_body_str);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_data);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);

    CURLcode res = curl_easy_perform(curl);
    long http_code = 0;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);

    curl_slist_free_all(headers);
    free(request_body_str);
    curl_easy_cleanup(curl);

    if (res != CURLE_OK) {
        LOG_ERROR("Failed to write tag: CURL error: %s", curl_easy_strerror(res));
        if (response_data) {
            free(response_data);
        }
        return NULL;
    }

    // 解析响应
    json_error_t error;
    json_t *root = json_loads(response_data, 0, &error);
    free(response_data);

    if (!root) {
        LOG_ERROR("Failed to parse write response JSON: %s", error.text);
        return NULL;
    }

    control_response_t *response = parse_control_response(root);
    json_decref(root);

    if (response) {
        if (response->error == 0) {
            LOG_INFO("Write tag successful: node=%s, group=%s, tag=%s", 
                    request->node, request->group, request->tag);
        } else {
            LOG_ERROR("Write tag failed: node=%s, group=%s, tag=%s, error=%d", 
                     request->node, request->group, request->tag, response->error);
        }
    }

    return response;
}

control_response_t *parse_control_response(json_t *json) {
    if (!json || !json_is_object(json)) {
        return NULL;
    }

    control_response_t *response = malloc(sizeof(control_response_t));
    if (!response) {
        return NULL;
    }
    memset(response, 0, sizeof(control_response_t));

    json_t *error_field = json_object_get(json, "error");
    if (error_field && json_is_integer(error_field)) {
        response->error = json_integer_value(error_field);
    } else {
        response->error = -1; // 未知错误
    }

    json_t *message_field = json_object_get(json, "message");
    if (message_field && json_is_string(message_field)) {
        response->message = strdup(json_string_value(message_field));
    }

    return response;
}

int device_manager_start_polling(device_manager_t *manager, int interval_ms) {
    if (!manager || !manager->initialized) {
        return ERROR_INVALID_PARAM;
    }

    // 先发现设备并同步标签
    device_manager_discover_devices(manager);
    
    // 同步所有组的标签信息
    pthread_rwlock_rdlock(&manager->rwlock);
    device_node_t *node = manager->device_tree;
    // 简化实现：遍历设备树并同步所有组
    // 实际应该根据设备树结构递归遍历
    pthread_rwlock_unlock(&manager->rwlock);

    // 添加定时轮询任务
    return timer_manager_add_task(manager->timer, "device_polling", interval_ms, 
                                 device_polling_callback, manager, false);
}

int device_manager_stop_polling(device_manager_t *manager) {
    if (!manager || !manager->initialized) {
        return ERROR_INVALID_PARAM;
    }

    return timer_manager_remove_task(manager->timer, "device_polling");
}

char *device_data_to_data_pool_key(const char *node, const char *group, const char *tag_name) {
    if (!node || !group || !tag_name) {
        return NULL;
    }

    // 生成数据池键，格式：device.{node}.{group}.{tag}
    size_t len = strlen("device.") + strlen(node) + strlen(group) + strlen(tag_name) + 3;
    char *key = malloc(len);
    if (!key) {
        return NULL;
    }

    snprintf(key, len, "device.%s.%s.%s", node, group, tag_name);
    return key;
}

void device_manager_cleanup(device_manager_t *manager) {
    if (!manager) {
        return;
    }

    device_manager_stop_polling(manager);

    if (manager->base_url) {
        free(manager->base_url);
    }
    if (manager->auth_token) {
        free(manager->auth_token);
    }

    // 清理设备树和组（简化实现）
    // 实际应该递归释放所有内存

    pthread_rwlock_destroy(&manager->rwlock);
    manager->initialized = false;
}
